package com.liu.sunnyday.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liu.sunnyday.dao.SetmealDao;
import com.liu.sunnyday.entity.QueryPageBean;
import com.liu.sunnyday.exception.SunnydayException;
import com.liu.sunnyday.pojo.CheckGroup;
import com.liu.sunnyday.pojo.Setmeal;
import com.liu.sunnyday.service.SetmealService;
import com.liu.sunnyday.utils.QiNiuUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = SetmealService.class)
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealDao setmealDao;

    /**
     * 1-分页查询所有套餐
     *
     * @param queryPageBean
     * @return
     */
    @Override
    public PageInfo<Setmeal> findPage(QueryPageBean queryPageBean) {
        //分页查询 拦截器思想
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        //判断搜索框中是否有条件需要查询
        if (!StringUtils.isEmpty(queryPageBean.getQueryString())) {
            queryPageBean.setQueryString("%" + queryPageBean.getQueryString() + "%");
        }
        //调用dao
        List<Setmeal> setmealList = setmealDao.findPageByCondition(queryPageBean.getQueryString());
        return new PageInfo<>(setmealList);
    }


    //2-新增套餐时，查询检查项
    @Override
    public List<CheckGroup> findAllgroup() {
        return setmealDao.findAllgroup();
    }

    //2-3新增套餐，点击确定
    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) {
        //1,添加套餐
        setmealDao.add(setmeal);
        //2，拿到新增套餐的id
        Integer setmeal_Id = setmeal.getId();

        //关于setmeal_id有两种情况：1，套餐关联的检查组可能是多个2，有可能没有一个
        //如果复选框内数组不为null，为空id则无需在中间表添加
        if (null != checkgroupIds) {
            for (Integer checkgroup_id : checkgroupIds) {
                setmealDao.addSetmealGroup(setmeal_Id, checkgroup_id);
            }
        }
        //第②部分：FreeMarker处理
        //a.新增套餐后需要重新生成静态页面
        generateMobileStaticHtml();
    }

    //3-3编辑套餐：查询复选框选中的检查组,根据套餐id查询，方便返回去回写,然后修改
    @Override
    public List<Integer> findCheckgroupIdsBySetmealId(Integer id) {
        return setmealDao.findCheckgroupIdsBySetmealId(id);
    }

    //3-4编辑套餐：点击确定提交数据
    @Override
    public void update(Setmeal setmeal, Integer[] checkgroupIds) {
        //修改检查组
        setmealDao.update(setmeal);
        //修改检查组关联的检查项:先全部解除
        setmealDao.deleteBYsID(setmeal.getId());
        //然后在建立
        //关于checkitem_ids有两种情况：1，检查组关联的检查项可能是多个2，有可能没有一个
        //如果复选框内无id则无需在中间表添加
        if (null != checkgroupIds) {
            for (Integer checkgroup_id : checkgroupIds) {
                setmealDao.insertById(setmeal.getId(), checkgroup_id);
            }
        }
    }

    //4删除套餐
    @Override
    @Transactional//事务
    public void deleteById(Integer id) throws SunnydayException {
        //删除，查询是否有与之关联的订单
        int count = setmealDao.findCountById(id);
        if (count > 0) {
            throw new SunnydayException("该套餐被订单订购！");
        }
        //删除与套餐关联的检查组
        setmealDao.deleteSGById(id);
        setmealDao.delete(id);
//        没有关联，直接删除，先删检查项和检查组的外键关联外键，在删检查组
//
//
//        //删除，一定是先查询他有没有被检查组关联
//        int count = checkgroupDao.findCountById(id);
//        if (count > 0) {
////            throw new SunnydayException("该检查项被检查组关联！");
//            checkgroupDao.deleteItemById(id);
//
//        }
//        int count1 = checkgroupDao.findcount1Byid(id);
//        if (count1 > 0) {
//            checkgroupDao.deletesById(id);
//        }
////        没有关联，直接删除，先删检查项和检查组的外键关联外键，在删检查组
//        checkgroupDao.deleteById(id);
    }


    /**
     * 处理套餐静态页面生成
     * 1个是套餐列表和多个套餐详情
     */
    private void generateMobileStaticHtml() {
        //1.处理1个套餐列表静态页面生成
        generateSetmealListHtml();
        //2.处理多个套餐列表静态页面生成
        generateSetmealDetailHtml();
    }

    /**
     * 处理1个套餐列表静态页面生成
     */
    private void generateSetmealListHtml() {
        //1.准备模板名称
        String templateName = "mobile_setmeal.ftl";
        //2.准备数据
        List<Setmeal> setmealList = setmealDao.findAll();
        //2.1设置好每一个套餐的图片地址
        setmealList.forEach(setmeal -> setmeal.setImg(QiNiuUtils.DOMAIN + setmeal.getImg()));
        //2.2 将数据添加到Map
        Map<String, Object> map = new HashMap<>();
        map.put("setmealList", setmealList);
        //3.出口
        String outFileName = out_put_path + "mobile_setmeal.html";
        //4.调用方法，执行页面静态化
        generateHtml(templateName, map, outFileName);
    }

    /**
     * 处理多个套餐列表静态页面生成
     */
    private void generateSetmealDetailHtml() {
        //1.准备模板名称
        String templateName = "mobile_setmeal_detail.ftl";
        //2.准备数据
        List<Setmeal> setmealList = setmealDao.findAll();
        //2.1遍历：设置图片路径是其一，并且还要取出套餐id
        for (Setmeal setmeal : setmealList) {
            //思考：setmeal有详情(应该还要包括检查组、检查项)吗？
            //2.2先通过每一个套餐的id查询出套餐详情
            Setmeal setmealDetail = setmealDao.findDetailById(setmeal.getId());//5表联查的详情
            //2.3设置图片
            setmealDetail.setImg(QiNiuUtils.DOMAIN + setmealDetail.getImg());
            //2.4 构架Map
            Map<String, Object> map = new HashMap<>();
            map.put("setmeal", setmealDetail);
            //3.输出路径（出口）
            String setmealDetailFile = out_put_path + "mobile_setmeal_" + setmealDetail.getId() + ".html";
            //4.执行页面静态化
            generateHtml(templateName, map, setmealDetailFile);
        }
    }



    @Override
    public List<String> findImgs() {
        return null;
    }


    //======================页面静态化的封装方法==============
    @Value("${out_put_path}")
    private String out_put_path;

    @Autowired
    private FreeMarkerConfig freeMarkerConfig;

    /**
     * 封装的FreeaMarker页面静态化方法
     * templateName:模板名称
     * dataMap:数据模板
     * outFileName：输出路径
     */
    public void generateHtml(String templateName, Map<String, Object> dataMap, String outFileName) {
        //1.创建配置类
        Configuration configuration = freeMarkerConfig.getConfiguration();
        BufferedWriter writer = null;
        try {
            //2.加载模板
            Template template = configuration.getTemplate(templateName);
            //3.构建数据模型
            //4.输出
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outFileName)), "utf-8"));
            //5.执行页面静态化
            template.process(dataMap, writer);
            //6.刷新缓冲流
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<Setmeal> findAll() {
        return setmealDao.findAll();
    }

    //3-编辑套餐：查询套餐回显
    @Override
    public Setmeal findById(Integer id) {
        return setmealDao.findById(id);
    }


    @Override
    public Setmeal findDetailById(Integer id) {
        return setmealDao.findById(id);
    }
}
